package com.yml.mall.carts;

import com.alibaba.fastjson.JSON;
import com.yml.mall.carts.pojo.CartsAddDTO;
import com.yml.mall.carts.pojo.CartsDO;
import com.yml.mall.carts.pojo.CartsDTO;
import com.yml.mall.carts.pojo.CartsVO;
import com.yml.mall.currentexception.MyException;
import com.yml.mall.currentexception.UserLoginException;
import com.yml.mall.enums.ResponseEnum;
import com.yml.mall.product.dao.ProductMapper;
import com.yml.mall.product.pojo.ProductDO;
import com.yml.mall.user.dao.UserMapper;
import com.yml.mall.user.pojo.UserDO;
import com.yml.mall.vo.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import static com.yml.mall.consts.myConst.CART_PRO_FIX;

/**
 * @ClassName CartsServiceImpl
 * @Author Administrator
 * @Date 2020/4/13   10:07
 */
@Service
@Slf4j
public class CartsServiceImpl implements CartsService {

    private  final  RedisTemplate<String , String> redisTemplate;
    private  final ProductMapper productMapper;
    private  final UserMapper userMapper;
    @Autowired
    public CartsServiceImpl(RedisTemplate<String, String> redisTemplate, ProductMapper productMapper, UserMapper userMapper){
        this.redisTemplate=redisTemplate;
        this.productMapper=productMapper;
        this.userMapper=userMapper;
    }



    @Override
    public ResponseVO<CartsVO> add(CartsAddDTO cartsAddDTO, UserDO userDO) {
        Integer quantity=cartsAddDTO.getQuantity()!=null?cartsAddDTO.getQuantity():Integer.valueOf(1);
        ProductDO productDO=productMapper.selectByPrimaryKey(cartsAddDTO.getProductId());
        //商品是否存在
        if(productDO ==null) {
            return ResponseVO.error(ResponseEnum.SALE_NOT_EXIST);
        }
        //商品是否在售
        if(productDO.getStatus()==2 || productDO.getStatus() ==3){
            return ResponseVO.error(ResponseEnum.SALE_OFF_OR_DELETE);
        }
        //商品库存是否充足
        if(productDO.getStock() <=0 ) {
            return ResponseVO.error(ResponseEnum.SALE_NOT_ENOUGH);
        }
        if(quantity>productDO.getStock()) {
            return ResponseVO.error(ResponseEnum.SALE_NOT_ENOUGH);
        }
        String redisKey = String.format(CART_PRO_FIX,userDO.getId());

        HashOperations<String,String, String> hashOperations=redisTemplate.opsForHash();
        String value= hashOperations.get(redisKey,String.valueOf(cartsAddDTO.getProductId()));


        CartsDO cartsDO = null;
        if(StringUtils.isEmpty(value)) {
            //购物车中不存在该商品
            cartsDO=new CartsDO(cartsAddDTO.getProductId(),quantity,cartsAddDTO.isSelected());
        }
        else {
            //购物车中存在该商品

            cartsDO=JSON.parseObject(value,CartsDO.class);
            cartsDO.setQuantity(quantity);
        }
        hashOperations.put(redisKey,String.valueOf(cartsAddDTO.getProductId()),JSON.toJSONString(cartsDO));
        if(quantity.equals(0))hashOperations.delete(redisKey,String.valueOf(cartsAddDTO.getProductId()));
        return getCartsVO(userDO);
    }


    @Override
    public ResponseVO<CartsVO> getCartsVO(UserDO userDO){
        //登录超时或者未登录
        if(userDO==null) throw new UserLoginException();
        UserDO user= userMapper.selectByPrimaryKey(userDO.getId());
        if(user==null) throw new UserLoginException();

        HashOperations<String,String, String> hashOperations=redisTemplate.opsForHash();
        String redisKey = String.format(CART_PRO_FIX,userDO.getId());
        List<String> values= hashOperations.values(redisKey);
        List<CartsDTO> cartsDTOList=new ArrayList<>();
        CartsVO cartsVO =new CartsVO();
        cartsVO.setCartTotalPrice(BigDecimal.valueOf(0));
        cartsVO.setSelectedAll(true);
        //
        for(int i=0;i<values.size();i++){
            CartsDO cartsDO=JSON.parseObject(values.get(i),CartsDO.class);
            if(cartsDO==null)break;
            ProductDO productDO=productMapper.selectByPrimaryKey(cartsDO.getProductId());
            if(productDO == null) throw new MyException(ResponseEnum.ERROR);
            CartsDTO cartsDTO=new CartsDTO();

            cartsDTO.setId(cartsDO.getProductId())
                    .setUserId(userDO.getId())
                    .setProductId(cartsDO.getProductId())
                    .setProductSubtitle(productDO.getSubtitle())
                    .setProductStock(productDO.getStock())
                    .setProductStatus(productDO.getStatus())
                    .setProductSelected(cartsDO.isProductSelected())
                    .setProductName(productDO.getName())
                    .setProductMainImage(productDO.getMainImage())
                    .setQuantity(cartsDO.getQuantity())
                    .setProductPrice(productDO.getPrice())
                    .setProductTotalPrice(productDO.getPrice().multiply(BigDecimal.valueOf(cartsDO.getQuantity())));
            if(!cartsDO.isProductSelected()) cartsVO.setSelectedAll(false);
            BigDecimal bigDecimal =cartsVO.getCartTotalPrice().add(cartsDTO.getProductTotalPrice());
            cartsVO.setCartTotalPrice(bigDecimal);
            cartsDTOList.add(cartsDTO);
        }

        if(cartsDTOList==null||cartsDTOList.size()<=0) cartsVO.setSelectedAll(false);
        cartsVO.setCartProductVoList(cartsDTOList);
        //System.out.println(values.toString());
        return  ResponseVO.success(cartsVO);
    }

    @Override
    public ResponseVO getCartsSum(UserDO userDO) {
        String redisKey=String.format(CART_PRO_FIX,userDO.getId());
        HashOperations<String,String, String> hashOperations=redisTemplate.opsForHash();
        List<String> list= hashOperations.values(redisKey);
        ResponseVO<Integer> responseVO= new ResponseVO<>(ResponseEnum.SUCCESS.getCode(),0);
        if(list!=null)  responseVO.setData(list.size());
        return responseVO;
    }



    private ResponseVO<ProductDO> judge(Integer productId){
        ProductDO productDO = productMapper.selectByPrimaryKey(productId);
        if(productDO==null)
            return ResponseVO.error(ResponseEnum.SALE_NOT_EXIST);
        if(productDO.getStatus().equals(2) || productDO.getStatus().equals(3))
            return ResponseVO.error(ResponseEnum.SALE_OFF_OR_DELETE);
        if(productDO.getStock()<=0)
            return ResponseVO.error(ResponseEnum.SALE_NOT_ENOUGH);
        return ResponseVO.success(productDO);
    }
}
